package se.hiq.wineo.client.widgets;

import java.util.ArrayList;

import se.hiq.wineo.client.widgets.common.EnumFieldWidget;
import se.hiq.wineo.client.widgets.common.FieldWidget;
import se.hiq.wineo.shared.Tools;
import se.hiq.wineo.shared.data.WineColor;
import se.hiq.wineo.shared.data.WineDetails;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextArea;

/**
 * This widget presents a detail view of a Wine. It lets the user edit fields and has functionality for saving the
 * changes made to database. It works equally well with existing and new wines.
 * 
 * @author joakimsah
 *
 */
public class WineViewWidget extends Composite {

	// Widgets in this Composite
	private Grid mainPanel;
	private Label wineViewLabel;
	private Grid winePanel;
	private FieldWidget nameField;
	private FieldWidget yearField;
	private FieldWidget alcField;
	private EnumFieldWidget<WineColor> colorField;
	private Label descriptionLabel;
	private TextArea descriptionTextArea;
	private Button saveButton;

	private WineDetails currentWine = null;
	
	private static String LABEL_WIDTH = "7em";
	
	public WineViewWidget() {
		mainPanel = new Grid(3, 1);
		mainPanel.setStyleName("wineViewWidget");
		
		wineViewLabel = new Label("Vin - detaljer");
		wineViewLabel.setStyleName("wineHeading");
		winePanel = new Grid(6, 1);
		winePanel.setStyleName("table-winedetails");
		winePanel.setCellPadding(0);
		winePanel.setCellSpacing(0);
		nameField = new FieldWidget("Namn", "", LABEL_WIDTH);
		yearField = new FieldWidget("År", "", LABEL_WIDTH);
		alcField = new FieldWidget("Alc.", "", LABEL_WIDTH);
		colorField = new EnumFieldWidget<WineColor>("Färg", WineColor.WHITE, WineColor.values(), LABEL_WIDTH);
		descriptionLabel = new Label("Beskrivning");
		descriptionTextArea = new TextArea();
		descriptionTextArea.setVisibleLines(5);
		descriptionTextArea.setCharacterWidth(30);
		saveButton = new Button("Spara");
		saveButton.addClickHandler(saveButtonClickHandler);
		
		winePanel.setWidget(0, 0, nameField);
		winePanel.setWidget(1, 0, yearField);
		winePanel.setWidget(2, 0, alcField);
		winePanel.setWidget(3, 0, colorField);
		winePanel.setWidget(4, 0, descriptionLabel);
		winePanel.setWidget(5, 0, descriptionTextArea);
		
		mainPanel.setWidget(0, 0, wineViewLabel);
		mainPanel.setWidget(1, 0, winePanel);
		mainPanel.setWidget(2, 0, saveButton);
		initWidget(mainPanel);
		
		updateCurrentWine();
	}
	
	// ----- Public methods -----
	
	/**
	 * Update this display to show given wine
	 * 
	 * @param wineDetails Wine to be displayed
	 */
	public void onWineSelected(WineDetails wineDetails) {
		this.currentWine = wineDetails;
		updateCurrentWine();
	}
	
	// ----- Private methods -----
	
	private void updateCurrentWine() {
		boolean enabled = (currentWine != null);
		nameField.setEnabled(enabled);
		yearField.setEnabled(enabled);
		alcField.setEnabled(enabled);
		colorField.setEnabled(enabled);
		descriptionTextArea.setEnabled(enabled);
		saveButton.setEnabled(enabled);
		
		if (enabled) {
			nameField.setValue(Tools.toStringOrEmpty(currentWine.getName()));
			yearField.setValue(Tools.toStringOrEmpty(currentWine.getYear()));
			alcField.setValue(Tools.toStringOrEmpty(currentWine.getAlc().toString()));
			colorField.setValue(currentWine.getColor());
			descriptionTextArea.setText(Tools.toStringOrEmpty(currentWine.getDescription()));
		} else {
			nameField.setValue("");
			yearField.setValue("");
			alcField.setValue("");
			colorField.setValue(null);
			descriptionTextArea.setText("");
		}
	}
	
	/**
	 * Used when saving the changes a user has made to a wine
	 * 
	 * @return List of errors in input fields
	 */
	private ArrayList<String> populateWineFromFields() {
		ArrayList<String> errors = new ArrayList<String>();
		if (currentWine != null) {
			currentWine.setName(nameField.getValue());
			try {
				currentWine.setYear(Tools.parseIntOrNull(yearField.getValue()));
			} catch (NumberFormatException nfe) {
				errors.add("Fältet år får endast innehålla siffror");
			}
			try {
				currentWine.setAlc(Tools.parseFloatOrNull(alcField.getValue()));
			} catch (NumberFormatException nfe) {
				errors.add("Fältet alc. får endast innehålla flyttal");
			}
			currentWine.setColor(colorField.getValue());
			currentWine.setDescription(descriptionTextArea.getText());
		} 
		return errors;
	}
	
	// ----- Classes for handling user input -----
	private ClickHandler saveButtonClickHandler = new ClickHandler() {
		@Override
		public void onClick(ClickEvent event) {
			ArrayList<String> errors = populateWineFromFields();
			if (errors.size() == 0) {
				// currentWine is now updated to contain the latest data from the input fields in this widget
				// TODO Implementation goes here!
				Window.alert("saveButtonClickHandler not fully implemented yet!");
			} else {
				StringBuilder sb = new StringBuilder("Följande fält innehåller fel:");
				for (String e : errors) {
					sb.append("\n - " + e);
				}
				Window.alert(sb.toString());
			}
		}
	};
}
